/******************************************
 * Author: Dave Spadea, Spadea Enterprises, Inc.
 * Date: November 2010
 * 
 * This code is released by Spadea Enterprises, Inc for general consumption 
 * under the Apache Software License.
 * 
 */


package net.spadea.framework.controller.logger;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import net.spadea.framework.messaging.Channel;
import net.spadea.framework.messaging.Message;
import net.spadea.framework.messaging.QueueChannel;
import net.spadea.framework.persistence.Database;
import net.spadea.framework.service.FrameworkService;

public class ControllerLoggerService extends FrameworkService {
	
	private PreparedStatement logInsert;

	public ControllerLoggerService() throws SQLException, ClassNotFoundException {
		Connection conn = Database.getNewConnection();
		Statement st = conn.createStatement();
		
		String logInsStmt = "INSERT INTO controller_log(" +
				"				id, version, application_guid, message_type, incoming_status, is_error," +
				"				dispatch_channel, dispatch_channel_type, message, message_guid, message_time" +
				"				)" +
				"			 VALUES (nextval('hibernate_sequence'), 0, ?, ?, ?, ?," +
				"					 ?, ?, ?, ?, CURRENT_TIMESTAMP)";
		
		logInsert = conn.prepareStatement(logInsStmt);
	}
	
	@Override
	public synchronized void processMessage(Message msg) throws Exception {
		
		logInsert.setString(1, msg.getApplicationID());
		logInsert.setString(2, msg.getMessageType());
		logInsert.setString(3, msg.getStatus());
		logInsert.setBoolean(4, Boolean.parseBoolean((String)msg.get("ErrorInfo", "is_error")));
		logInsert.setString(5, msg.getHeader("routed_to"));
		logInsert.setString(6, (String) msg.getHeader("route_type"));
		
		// Log the fact that the message existed and was routed, but don't log the message contents.
		// This will obviously preclude resubmission of the events, but is good for things like 
		// credit card processing where you don't want credit card numbers sitting around in the controller log.
		if(shouldLogContent(msg)) {
			logInsert.setString(7, msg.toString());
		}
		else {
			logInsert.setString(7, "<PRIVATE>");
		}
		
		logInsert.setString(8, msg.getHeader("message_id"));
		
		log.info("Executing insert:\n" + logInsert.toString());
	
		logInsert.executeUpdate();
		

	}
	
	@Override
	public Channel listenChannel() {
		return new QueueChannel("controller.log");
	}
	
	protected boolean shouldLogContent(Message msg) {

		if(Message.SENSITIVITY_PRIVATE.equalsIgnoreCase(msg.getSensitivity())) {
			log.info("Sensitivity = " + msg.getSensitivity() + ". Will not log content.");
			return false;
		}
		
		log.info("Sensitivity = " + msg.getSensitivity() + ". Will log content of message.");
		return true;
		
	}

}
